﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.Decompiler.Disassembler;
using JetBrains.Decompiler;
using Mono.Cecil;


namespace Obfuscator
{
    public class SharpDecompiler
    {
        public DecompilerSettings DecompilerSettings { get; set; }

        public SharpDecompiler(AssemblyDefinition assemblyDefinition)
        {
            AssemblyDefinitionToDecompile = assemblyDefinition;
            DecompilerSettings = new DecompilerSettings() { FullyQualifyAmbiguousTypeNames = true };
            var resolver = new DefaultAssemblyResolver();

            var parameters = new ReaderParameters
            {
                AssemblyResolver = resolver,
            };
        }

        public SharpDecompiler(string assemblyPath)
        {
            AssemblyDefinitionToDecompile = AssemblyDefinition.ReadAssembly(assemblyPath); ;
            DecompilerSettings = new DecompilerSettings() { FullyQualifyAmbiguousTypeNames = true };
            var resolver = new DefaultAssemblyResolver();

            var parameters = new ReaderParameters
            {
                AssemblyResolver = resolver,
            };
        }


        public void DecompileAssembly()
        {
            var decompilerContext = new DecompilerContext(AssemblyDefinitionToDecompile.MainModule)
            {
                //Settings = DecompilerSettings
            };
            var astBuilder = new AstBuilder(decompilerContext);
            astBuilder.AddAssembly(AssemblyDefinitionToDecompile);

            var output = new StringWriter();
            astBuilder.GenerateCode(new PlainTextOutput(output));

            var byteArray = Encoding.ASCII.GetBytes(output.ToString());
            var codeReader = new StreamReader(new MemoryStream(byteArray));
            DecompiledCode = codeReader.ReadToEnd();
        }

        public AssemblyDefinition AssemblyDefinitionToDecompile { get; set; }
        public string DecompiledCode { get; set; }
    }

}

